#include <stdlib.h>
#include <stdio.h>

#include "dtk_types.h"
#include "dtk_debug.h"

#include "dtk_vsmanager.h"

DTKVisualStateManager* dtk_vsm_create()
{
    DTKVisualStateManager* vsm;

    vsm = (DTKVisualStateManager*) malloc (sizeof(DTKVisualStateManager));
    memset (vsm, 0, sizeof(DTKVisualStateManager));

    return vsm;
}

static DBoolean vsm_free(DList* list, DLink* link, va_list args)
{
    DTKVisualStateGroup* group = (DTKVisualStateGroup*)DLINKDATA(link);
    dtk_list_remove (list, link);
    dtk_vsg_free(group);
    return DTK_FALSE;
}

void dtk_vsm_free(DTKVisualStateManager* self)
{
    if (self == NULL)
    {
        return;
    }

    dtk_list_foreach(DLIST(self), vsm_free);
    free (self);
    return;
}

void dtk_vsm_remove(DTKVisualStateManager* self, DTKVisualStateGroup* vsg)
{
    if (self == NULL || vsg == NULL)
    {
        return;
    }

    dtk_list_remove(DLIST(self), DLINK(vsg));
    return;
}

static DBoolean add_vsg(DList* list, DLink* link, va_list args)
{
    DTKVisualStateGroup* group = (DTKVisualStateGroup*)DLINKDATA(link);
    DTKVisualStateGroup* new_group;

    new_group = va_arg(args, DTKVisualStateGroup*);

    if (group->id == new_group->id)
    {
        dtk_list_remove(list, link);
        dtk_vsg_free(group);
        return DTK_TRUE;
    }

    return DTK_FALSE;
}


void dtk_vsm_add(DTKVisualStateManager* self, DTKVisualStateGroup* vsg)
{
    if (self == NULL || vsg == NULL)
    {
        return;
    }

    if (dtk_list_contains_element (DLIST(self), DLINK(vsg)))
    {
        return;
    }

    dtk_list_foreach(DLIST(self), add_vsg, vsg);
    dtk_list_append (DLIST(self), DLINK(vsg));
    
    return;
}

static DBoolean get_vsg(DList* list, DLink* link, va_list args)
{
    DTKVisualStateGroup* group = (DTKVisualStateGroup*)DLINKDATA(link);
    DInt id;
    DTKVisualStateGroup** ret_group;

    id = va_arg(args, DInt);
    ret_group = va_arg(args, DTKVisualStateGroup**);

    if (group->id == id)
    {
        *ret_group = group;
        return DTK_TRUE;
    }

    return DTK_FALSE;
}

DTKVisualStateGroup* dtk_vsm_get_group (DTKVisualStateManager* self, DInt id)
{
    DTKVisualStateGroup* vsg = NULL;

    if (self == NULL)
    {
        return NULL;
    }

    dtk_list_foreach(DLIST(self), get_vsg, id, &vsg);

    return NULL;
}

static DBoolean goto_state(DList* list, DLink* link, va_list args)
{
    DTKVisualStateGroup* vsg = (DTKVisualStateGroup*)DLINKDATA(link);
    DInt state;
    DBoolean ret;

    state = va_arg(args, DInt);

    return dtk_vsg_goto_state(vsg, state);    
}

void dtk_vsm_goto_state(DTKVisualStateManager* self, DInt state)
{
    DTKVisualStateGroup* vsg = NULL;
    DBoolean ret;

    if (self == NULL)
    {
        return;
    }

    dtk_list_foreach (DLIST(self), goto_state, state);
    return;
}

